package org.lwjgltutorial.chapter3;

import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_LINE_LOOP;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glFlush;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glVertex3f;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;

public class AnimatedSquare {

	private static final int WINDOW_HEIGHT = 600;
	private static final int WINDOW_WIDTH = 800;

	public AnimatedSquare(){
		init();
	}
	private void init() {
		// find out what the current bits per pixel of the desktop is
		int currentBpp = Display.getDisplayMode().getBitsPerPixel();
		// find a display mode at 800x600
		try {
			DisplayMode mode = findDisplayMode(WINDOW_WIDTH, WINDOW_HEIGHT,
					currentBpp);
			Display.setDisplayMode(mode);
			Display.setFullscreen(false);
			Display.setTitle("Animated Square");
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
		}

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		double aspectRatio = (double)WINDOW_WIDTH/WINDOW_HEIGHT;
		GLU.gluPerspective(
				45.0f,        // Field Of View
				(float)aspectRatio, // aspect ratio
				0.001f,         // near Z clipping plane
				10.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();

	}

	private void loop() {
		long currentTime = System.currentTimeMillis();
		int frames = 0;
		// wait for close
		while(!Display.isCloseRequested()){
			glClear(GL_COLOR_BUFFER_BIT);
			glRotatef(0.1f, 0, 0, -3);
			render();
			// update window.
			Display.update();
			if(System.currentTimeMillis()-currentTime>1000){
				Display.setTitle("Animated Square "+frames+" fps");
				frames = 0;
				currentTime = System.currentTimeMillis();
			}
			frames++;
		}
		Display.destroy();
	}

	private void render() {
		// draw the square near to the viewer
		glBegin(GL_LINE_LOOP);
		glVertex3f(-0.5f, -0.5f, -3f);
		glVertex3f(-0.5f, 0.5f, -3f);
		glVertex3f(0.5f, 0.5f, -3f);
		glVertex3f(0.5f, -0.5f, -3f);
		glEnd();
		// flush any commands that are still hanging about.
		glFlush();
	}


	private DisplayMode findDisplayMode(int width, int height, int bpp) throws LWJGLException {
		DisplayMode[] modes = Display.getAvailableDisplayModes();
		DisplayMode mode = null;

		for (int i=0;i<modes.length;i++) {
			if ((modes[i].getBitsPerPixel() == bpp) || (mode == null)) {
				if ((modes[i].getWidth() == width) && (modes[i].getHeight() == height)) {
					mode = modes[i];
				}
			}
		}

		return mode;
	}

	public static void main(String[] args) throws InterruptedException{

		AnimatedSquare square = new AnimatedSquare();
		square.loop();

	}
}
